package com.caseprocessing.service;

import com.caseprocessing.model.*;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * 档案著录信息提取器
 * 基于DA/T 18-1999标准提取和生成档案著录信息
 */
public class ArchivalDescriptionExtractor {
    
    // 常用的主题词词典
    private static final Map<String, List<String>> SUBJECT_TERMS_DICT = new HashMap<>();
    
    // 法律依据识别模式
    private static final Pattern LEGAL_BASIS_PATTERN = 
        Pattern.compile("(《[^》]+》第[\\d]+条|《[^》]+》|[\\u4e00-\\u9fa5]+法第[\\d]+条)");
    
    // 案件类型识别模式
    private static final Pattern CASE_TYPE_PATTERN = 
        Pattern.compile("(行政处罚|行政许可|行政强制|行政检查|行政确认)");
    
    static {
        // 初始化主题词词典
        SUBJECT_TERMS_DICT.put("行政处罚", Arrays.asList("处罚决定", "违法行为", "法律责任", "执法程序"));
        SUBJECT_TERMS_DICT.put("行政许可", Arrays.asList("许可申请", "审查批准", "许可证", "行政审批"));
        SUBJECT_TERMS_DICT.put("行政强制", Arrays.asList("强制执行", "查封扣押", "冻结", "强制措施"));
    }
    
    /**
     * 从案卷文档中提取档案著录信息
     */
    public ArchivalDescription extractArchivalDescription(CaseDocument caseDoc) {
        ArchivalDescription description = new ArchivalDescription();
        
        // 1. 从封面页提取基础信息
        extractBasicInfoFromCover(caseDoc, description);
        
        // 2. 从文档内容提取业务信息
        extractBusinessInfoFromContent(caseDoc, description);
        
        // 3. 生成主题词和关键词
        generateSubjectTermsAndKeywords(caseDoc, description);
        
        // 4. 设置载体信息
        setCarrierInformation(caseDoc, description);
        
        // 5. 生成提要信息
        generateSummary(caseDoc, description);
        
        // 6. 设置默认的密级和保管期限
        setDefaultSecurityAndRetention(description);
        
        return description;
    }
    
    /**
     * 从封面页提取基础信息
     */
    private void extractBasicInfoFromCover(CaseDocument caseDoc, ArchivalDescription description) {
        // 查找封面页
        Page coverPage = findCoverPage(caseDoc);
        if (coverPage == null) return;
        
        String coverContent = coverPage.getFullText();
        
        // 提取全宗名称
        String fondName = extractFondName(coverContent);
        description.setFondName(fondName);
        
        // 提取类目名称
        String categoryName = extractCategoryName(coverContent);
        description.setCategoryName(categoryName);
        
        // 提取立档单位
        String filingUnit = extractFilingUnit(coverContent);
        description.setFilingUnit(filingUnit);
    }
    
    /**
     * 查找封面页
     */
    private Page findCoverPage(CaseDocument caseDoc) {
        return caseDoc.getPages().stream()
                .filter(page -> {
                    String content = page.getFullText().toLowerCase();
                    return content.contains("全宗名称") || 
                           content.contains("类目名称") ||
                           content.contains("案卷题名");
                })
                .findFirst()
                .orElse(caseDoc.getPages().isEmpty() ? null : caseDoc.getPages().get(0));
    }
    
    /**
     * 提取全宗名称
     */
    private String extractFondName(String content) {
        // 查找全宗名称模式
        Pattern pattern = Pattern.compile("全宗名称[：:\\s]*([\\u4e00-\\u9fa5\\w\\s]+)");
        Matcher matcher = pattern.matcher(content);
        
        if (matcher.find()) {
            return matcher.group(1).trim();
        }
        
        // 如果没有明确标识，尝试从机关名称推断
        String[] agencyKeywords = {"人民政府", "执法局", "监察局", "公安局", "工商局"};
        for (String keyword : agencyKeywords) {
            if (content.contains(keyword)) {
                int index = content.indexOf(keyword);
                // 提取机关全名
                String surrounding = content.substring(Math.max(0, index - 10), 
                                                     Math.min(content.length(), index + keyword.length() + 5));
                return extractAgencyFullName(surrounding);
            }
        }
        
        return ""; // 默认空值
    }
    
    /**
     * 提取机关全名
     */
    private String extractAgencyFullName(String text) {
        // 简化实现：提取包含关键词的完整机关名称
        Pattern pattern = Pattern.compile("([\\u4e00-\\u9fa5]{2,}(人民政府|执法局|监察局|公安局|工商局)[\\u4e00-\\u9fa5]*)");
        Matcher matcher = pattern.matcher(text);
        
        if (matcher.find()) {
            return matcher.group(1);
        }
        
        return text.trim();
    }
    
    /**
     * 提取类目名称
     */
    private String extractCategoryName(String content) {
        Pattern pattern = Pattern.compile("类目名称[：:\\s]*([\\u4e00-\\u9fa5\\w\\s]+)");
        Matcher matcher = pattern.matcher(content);
        
        if (matcher.find()) {
            return matcher.group(1).trim();
        }
        
        // 根据案件内容推断类目
        if (content.contains("行政处罚")) {
            return "行政执法";
        } else if (content.contains("行政许可")) {
            return "行政审批";
        } else if (content.contains("行政强制")) {
            return "行政强制";
        }
        
        return "综合管理"; // 默认类目
    }
    
    /**
     * 提取立档单位
     */
    private String extractFilingUnit(String content) {
        // 通常立档单位就是执法机关
        return extractFondName(content);
    }
    
    /**
     * 从文档内容提取业务信息
     */
    private void extractBusinessInfoFromContent(CaseDocument caseDoc, ArchivalDescription description) {
        String allContent = getAllDocumentContent(caseDoc);
        
        // 提取案件类型
        String caseType = extractCaseType(allContent);
        description.setCaseType(caseType);
        
        // 提取法律依据
        List<String> legalBasis = extractLegalBasis(allContent);
        description.setLegalBasis(String.join("; ", legalBasis));
        
        // 提取执法阶段
        String enforcementStage = determineEnforcementStage(caseDoc);
        description.setEnforcementStage(enforcementStage);
        
        // 从备考表提取立卷信息
        extractFilingInfoFromBackupTable(caseDoc, description);
    }
    
    /**
     * 获取所有文档内容
     */
    private String getAllDocumentContent(CaseDocument caseDoc) {
        StringBuilder content = new StringBuilder();
        for (Page page : caseDoc.getPages()) {
            content.append(page.getFullText()).append(" ");
        }
        return content.toString();
    }
    
    /**
     * 提取案件类型
     */
    private String extractCaseType(String content) {
        Matcher matcher = CASE_TYPE_PATTERN.matcher(content);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return "行政执法"; // 默认类型
    }
    
    /**
     * 提取法律依据
     */
    private List<String> extractLegalBasis(String content) {
        List<String> legalBasisList = new ArrayList<>();
        Matcher matcher = LEGAL_BASIS_PATTERN.matcher(content);
        
        while (matcher.find()) {
            String basis = matcher.group(1);
            if (!legalBasisList.contains(basis)) {
                legalBasisList.add(basis);
            }
        }
        
        return legalBasisList;
    }
    
    /**
     * 确定执法阶段
     */
    private String determineEnforcementStage(CaseDocument caseDoc) {
        Map<DocumentType, Integer> typeCount = new HashMap<>();
        
        // 统计文书类型分布
        for (Page page : caseDoc.getPages()) {
            // 简化实现：根据页面内容推断文书类型
            String content = page.getFullText().toLowerCase();
            
            if (content.contains("立案") || content.contains("受理")) {
                typeCount.put(DocumentType.OTHER, typeCount.getOrDefault(DocumentType.OTHER, 0) + 1);
            } else if (content.contains("调查") || content.contains("询问")) {
                typeCount.put(DocumentType.INVESTIGATION_RECORD, typeCount.getOrDefault(DocumentType.INVESTIGATION_RECORD, 0) + 1);
            } else if (content.contains("告知")) {
                typeCount.put(DocumentType.NOTIFICATION, typeCount.getOrDefault(DocumentType.NOTIFICATION, 0) + 1);
            } else if (content.contains("听证")) {
                typeCount.put(DocumentType.HEARING_RECORD, typeCount.getOrDefault(DocumentType.HEARING_RECORD, 0) + 1);
            } else if (content.contains("决定")) {
                typeCount.put(DocumentType.CASE_DECISION, typeCount.getOrDefault(DocumentType.CASE_DECISION, 0) + 1);
            }
        }
        
        // 根据文书完整性判断执法阶段
        if (typeCount.containsKey(DocumentType.CASE_DECISION)) {
            return "执法完成";
        } else if (typeCount.containsKey(DocumentType.HEARING_RECORD)) {
            return "听证阶段";
        } else if (typeCount.containsKey(DocumentType.NOTIFICATION)) {
            return "告知阶段";
        } else if (typeCount.containsKey(DocumentType.INVESTIGATION_RECORD)) {
            return "调查阶段";
        } else {
            return "立案阶段";
        }
    }
    
    /**
     * 从备考表提取立卷信息
     */
    private void extractFilingInfoFromBackupTable(CaseDocument caseDoc, ArchivalDescription description) {
        // 查找备考表页
        Page backupTablePage = findBackupTablePage(caseDoc);
        if (backupTablePage == null) return;
        
        String content = backupTablePage.getFullText();
        
        // 提取立卷人
        String filingPerson = extractFieldValue(content, "立卷人");
        description.setFilingPerson(filingPerson);
        
        // 提取检查人
        String reviewer = extractFieldValue(content, "检查人");
        description.setReviewer(reviewer);
        
        // 提取立卷时间
        String filingDate = extractFieldValue(content, "立卷时间|立卷日期");
        description.setFilingDate(filingDate);
    }
    
    /**
     * 查找备考表页
     */
    private Page findBackupTablePage(CaseDocument caseDoc) {
        return caseDoc.getPages().stream()
                .filter(page -> {
                    String content = page.getFullText();
                    return content.contains("卷内备考表") || 
                           content.contains("立卷人") || 
                           content.contains("检查人");
                })
                .findFirst()
                .orElse(null);
    }
    
    /**
     * 提取字段值
     */
    private String extractFieldValue(String content, String fieldPattern) {
        Pattern pattern = Pattern.compile("(" + fieldPattern + ")[：:\\s]*([\\u4e00-\\u9fa5\\w\\s]+)");
        Matcher matcher = pattern.matcher(content);
        
        if (matcher.find()) {
            return matcher.group(2).trim();
        }
        
        return "";
    }
    
    /**
     * 生成主题词和关键词
     */
    private void generateSubjectTermsAndKeywords(CaseDocument caseDoc, ArchivalDescription description) {
        String allContent = getAllDocumentContent(caseDoc);
        
        // 提取关键词
        List<String> keywords = extractKeywords(allContent);
        description.setKeywords(keywords);
        
        // 生成规范化主题词
        List<String> subjectTerms = generateSubjectTerms(description.getCaseType(), keywords);
        description.setSubjectTerms(subjectTerms);
    }
    
    /**
     * 提取关键词
     */
    private List<String> extractKeywords(String content) {
        List<String> keywords = new ArrayList<>();
        
        // 法律关键词
        String[] legalKeywords = {"处罚", "违法", "责任", "决定", "执法", "调查", "证据", "听证"};
        for (String keyword : legalKeywords) {
            if (content.contains(keyword)) {
                keywords.add(keyword);
            }
        }
        
        // 限制关键词数量
        return keywords.size() > 10 ? keywords.subList(0, 10) : keywords;
    }
    
    /**
     * 生成规范化主题词
     */
    private List<String> generateSubjectTerms(String caseType, List<String> keywords) {
        List<String> subjectTerms = new ArrayList<>();
        
        // 从词典获取相关主题词
        if (caseType != null && SUBJECT_TERMS_DICT.containsKey(caseType)) {
            subjectTerms.addAll(SUBJECT_TERMS_DICT.get(caseType));
        }
        
        // 添加通用主题词
        subjectTerms.add("行政执法");
        subjectTerms.add("案卷文书");
        
        return subjectTerms;
    }
    
    /**
     * 设置载体信息
     */
    private void setCarrierInformation(CaseDocument caseDoc, ArchivalDescription description) {
        // 扫描后的PDF文档
        description.setCarrierType(ArchivalDescription.CarrierType.OPTICAL_DISK);
        
        // 设置数量信息
        description.setQuantity(caseDoc.getTotalPages() + "页");
        
        // 设置规格信息（PDF格式）
        description.setSpecifications("PDF格式，A4规格扫描件");
    }
    
    /**
     * 生成提要信息
     */
    private void generateSummary(CaseDocument caseDoc, ArchivalDescription description) {
        StringBuilder summary = new StringBuilder();
        
        // 案件基本情况
        if (description.getCaseType() != null) {
            summary.append(description.getCaseType()).append("案件，");
        }
        
        // 文书数量
        summary.append("共").append(caseDoc.getTotalPages()).append("页，");
        
        // 主要内容
        if (description.getLegalBasis() != null && !description.getLegalBasis().isEmpty()) {
            summary.append("依据").append(description.getLegalBasis()).append("，");
        }
        
        // 执法阶段
        if (description.getEnforcementStage() != null) {
            summary.append("案件处于").append(description.getEnforcementStage()).append("。");
        }
        
        // 限制提要长度（不超过200字）
        String summaryText = summary.toString();
        if (summaryText.length() > 200) {
            summaryText = summaryText.substring(0, 197) + "...";
        }
        
        description.setSummary(summaryText);
    }
    
    /**
     * 设置默认的密级和保管期限
     */
    private void setDefaultSecurityAndRetention(ArchivalDescription description) {
        // 默认密级：内部级（行政执法案件通常为内部级）
        description.setSecurityLevel(ArchivalDescription.SecurityLevel.INTERNAL);
        
        // 默认保管期限：长期（执法案件通常需要长期保存）
        description.setRetentionPeriod(ArchivalDescription.RetentionPeriod.LONG_TERM);
    }
    
    /**
     * 验证著录信息完整性
     */
    public ValidationResult validateArchivalDescription(ArchivalDescription description) {
        List<String> issues = new ArrayList<>();
        
        // 检查必填项
        if (description.getFondName() == null || description.getFondName().trim().isEmpty()) {
            issues.add("全宗名称不能为空");
        }
        
        if (description.getCategoryName() == null || description.getCategoryName().trim().isEmpty()) {
            issues.add("类目名称不能为空");
        }
        
        if (description.getFilingUnit() == null || description.getFilingUnit().trim().isEmpty()) {
            issues.add("立档单位不能为空");
        }
        
        // 检查著录规范性
        if (description.getKeywords() == null || description.getKeywords().isEmpty()) {
            issues.add("缺少主题词或关键词");
        }
        
        if (description.getSummary() == null || description.getSummary().length() < 10) {
            issues.add("提要内容过短或缺失");
        }
        
        return new ValidationResult(issues.isEmpty(), issues);
    }
}